package com.adtech.adms.system.service.impl;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;

import com.adtech.adms.commons.tree.FeatureTreeNode;
import com.adtech.adms.commons.tree.TopoTreeNode;
import com.adtech.adms.commons.tree.TreeNode;
import com.adtech.adms.system.SystemConstants;
import com.adtech.adms.system.dao.TopoDAO;
import com.adtech.adms.system.pojo.Feature;
import com.adtech.adms.system.pojo.Role;
import com.adtech.adms.system.pojo.Topo;
import com.adtech.adms.system.pojo.User;
import com.adtech.adms.system.service.TopoService;
import com.adtech.core.cache.Cache;
import com.adtech.core.dao.exp.Condition;
import com.adtech.core.dao.exp.Expression;
import com.adtech.core.dao.query.Pager;
import com.adtech.core.dao.query.QueryConstants;
import com.adtech.core.dao.query.QueryCriterions;
import com.adtech.core.dao.query.Sort;
import com.adtech.core.exception.ServiceException;

public class TopoServiceImpl implements TopoService{

	private TopoDAO topoDAO;
	private Cache templateCache;


	
	public Cache getTemplateCache() {
		return templateCache;
	}

	public void setTemplateCache(Cache templateCache) {
		this.templateCache = templateCache;
	}

	public void setTopoDAO(TopoDAO topoDAO) {
		this.topoDAO = topoDAO;
	}

	@Override
	public List<TreeNode<Topo>> getTopoTree(boolean allLevel) {
		
		List<Topo> topos=(List<Topo>)topoDAO.getByQuery(Topo.class, null);
		
		
		List<TreeNode<Topo>> nodes=new ArrayList<TreeNode<Topo>>();
		for (Topo topo : topos) {
			if(topo.getParent() != null){
				continue;
			}
			TopoTreeNode node = new TopoTreeNode(topo);
			if(allLevel) {
				node.setNodes(initNodes(topo.getChildren(), node));
			} else {
				if(topo.getChildren().size()>0) {
					node.setIsParent(true);
//					node.setHalfChecked(isHalfChecked(topo,role));
				} else {
					node.setIsParent(false);
				}
			}
			nodes.add(node);
		}
		
		return nodes;
	}
	
	@Override
	public List<TreeNode<Topo>> getTopoTree(Long id, boolean allLevel) {
		Expression expression = Condition.eq(SystemConstants.Topo.PARENT + "." + SystemConstants.Topo.ID, id);
		List<Topo> topos=(List<Topo>)topoDAO.getByQuery(Topo.class, expression);
		List<TreeNode<Topo>> nodes=new ArrayList<TreeNode<Topo>>();
		for (Topo topo : topos) {
//			if(topo.getParent() != null){
//				continue;
//			}
			TopoTreeNode node = new TopoTreeNode(topo);
			if(allLevel) {
				node.setNodes(initNodes(topo.getChildren(), node));
			} else {
				if(topo.getChildren().size()>0) {
					node.setIsParent(true);
//					node.setHalfChecked(isHalfChecked(topo,role));
				} else {
					node.setIsParent(false);
				}
			}
			nodes.add(node);
		}
		
		return nodes;
	}

	
	
	@Override
	public Topo getTopoById(Long id) {
		return topoDAO.getById(Topo.class, id);
	}
	
	/**
	 * 是否此权限以及其所有子权限都被选中
	 * @param feature
	 * @return
	 * @author Dormin
	 */
//	private boolean isHalfChecked(Topo topo,Role role) {
//		if(role==null || role.getRoleId()==null) {
//			return false;
//		}
//		return topoDAO.isHalfChecked(feature, role);
//	}
	

	private final List<TreeNode<Topo>> initNodes(List<Topo> topos, TreeNode<Topo> parent) {
		List<TreeNode<Topo>> nodes = null;
		if (topos != null && topos.size() > 0) {
			nodes = new ArrayList<TreeNode<Topo>>();
			for (Topo topo : topos) {
				topoDAO.initialize(topo);
				TreeNode<Topo> node = new TopoTreeNode(topo);
				node.setNodes(initNodes(topo.getChildren(), parent));
				nodes.add(node);
			}
		}
		return nodes;
	}
	
	@Override
	public List<Role> getTopoList(Pager pager) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public void delete(Long id, User user) throws ServiceException {
		
		topoDAO.delete(Topo.class, id);
	}

	@Override
	public void save(Long slectId,Topo topo, User user) throws ServiceException {
//		if (feature.getRoot()!=null&&!feature.getRoot()) {
//			QueryCriterions hc = new QueryCriterions();
//			hc.and(SystemConstants.Feature.FEATURE_ID, feature.getParent().getId(), QueryConstants.EQ);
//			Feature parent = featureDAO.getOneByQuery(Feature.class, hc.toExpression());
//			feature.setParent(parent);
//		} else {
//			feature.setParent(null);
//		}
		if(topo.getId() == null){//add
			
		    topo.setPath(topo.getName());
			
			topo.setCreateDate(new Timestamp(System.currentTimeMillis()));
			topo.setEditDate(new Timestamp(System.currentTimeMillis()));
			if(topo.getParent()!=null){
				Topo parentTop = topoDAO.getById(Topo.class, topo.getParent().getId());
				topo.setFullPath(parentTop.getFullPath()+"."+topo.getName());
				topo.setParent(parentTop);
				topo.setIdPath(parentTop.getIdPath()+"."+topo.getNodeid());
			}else{//root
				topo.setFullPath(topo.getName());
				topo.setIdPath(topo.getNodeid());
			}
			
//			Topo parentTop = topo.getParent();
			topo.setIdPath(topo.getIdPath());
			
			topoDAO.saveOrUpdate(topo);
		}else{//edit
			Topo pTopo=topoDAO.getById(Topo.class, topo.getId());
			pTopo.setName(topo.getName());
			pTopo.setIdPath(topo.getIdPath());
			Topo parentTop = pTopo.getParent();
			
			if(parentTop!=null){
				pTopo.setFullPath(parentTop.getFullPath()+"."+topo.getName());
//				topo.setFullPath(parentTop.getFullPath()+"."+topo.getName());
				pTopo.setParent(parentTop);
				pTopo.setIdPath(parentTop.getIdPath()+"."+topo.getNodeid());
				pTopo.setNodeid(topo.getNodeid());
			}else{
				pTopo.setFullPath(topo.getName());
				pTopo.setIdPath(topo.getNodeid());
				pTopo.setNodeid(topo.getNodeid());
			}
			
			
			pTopo.setEditDate(new Timestamp(System.currentTimeMillis()));
			
			topoDAO.saveOrUpdate(pTopo);
		}
		
		
//		topo.setCreateDate(new Timestamp(System.currentTimeMillis()));
//		topo.setEditDate(new Timestamp(System.currentTimeMillis()));
//		
//		if(topo.getId()!=null){
//			
//			
////			pTopo.setCode(topo.getCode());
////			pTopo.setUrl(topo.getUrl());
////			pTopo.setComments(topo.getComments());
////			pTopo.setUrlTarget(topo.getUrlTarget());
////			pTopo.setEntryType(topo.getEntryType());
//////			pTopo.setSerialNumber(feature.getSerialNumber());
////			pTopo.setClasses(topo.getClasses());
//			
//			if(parentTop!=null){
//				
//			}
//			topoDAO.saveOrUpdate(pTopo);
//		}
//		else {
//			topoDAO.saveOrUpdate(topo);
//		}
		
	}

//	@Override
//	public List<TreeNode<Topo>> getTopoTree(Long id, boolean allLevel, Topo topo) {
//		// TODO Auto-generated method stub
//		return null;
//	}





}
